package com.lyubia.shop.manager.service.impl;

import com.lyubia.shop.common.result.BaseResult;
import com.lyubia.shop.manager.mapper.GoodsCategoryMapper;
import com.lyubia.shop.manager.pojo.GoodsCategory;
import com.lyubia.shop.manager.pojo.GoodsCategoryExample;
import com.lyubia.shop.manager.service.GoodsCategoryService;
import com.lyubia.shop.common.utils.AssertUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class GoodsCategoryServiceImpl implements GoodsCategoryService {

    @Resource
    private GoodsCategoryMapper goodsCategoryMapper;

    @Resource(name = "redisTemplate")
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 根据parentId查询子集分类
     * @param parentId 父id
     * @return 列表
     */
    @Override
    public List<GoodsCategory> selectCategoryByParentId(Short parentId) {
        AssertUtil.isTrue(parentId == null || parentId < 0,"父ID不合法!");
        GoodsCategoryExample example = new GoodsCategoryExample();
        example.createCriteria().andParentIdEqualTo(parentId);
        return goodsCategoryMapper.selectByExample(example);
    }

    /**
     * 查询一级商品分类
     * @return 结果集
     */
    @Override
    public List<GoodsCategory> selectTopCategory() {
        return selectCategoryByParentId((short) 0);
    }

    /**
     * 保存商品分类
     * @param goodsCategory 商品分类信息
     * @return 结果集
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public BaseResult saveGoodsCategory(GoodsCategory goodsCategory) {
        AssertUtil.isTrue(goodsCategory == null,"新增信息为空!");
        int i = goodsCategoryMapper.insertSelective(goodsCategory);
        if (i > 0) {
            StringBuilder sb = new StringBuilder();
            if (goodsCategory.getParentId()==0) {
                sb.append("0_").append(goodsCategory.getId());
            } else {
                GoodsCategory parent = goodsCategoryMapper.selectByPrimaryKey(goodsCategory.getParentId());
                sb.append(parent.getParentIdPath()).append("_").append(goodsCategory.getId());
            }
            goodsCategory.setParentIdPath(sb.toString());
            int j = goodsCategoryMapper.updateByPrimaryKeySelective(goodsCategory);
            if (j > 0)
                return BaseResult.success();
        }
        return BaseResult.error();
    }

    /**
     * 查询全部三级分类
     * @return 列表
     */
    @Override
    public List<GoodsCategory> selectCategoryAndChild() {
        GoodsCategoryExample example = new GoodsCategoryExample();
        List<GoodsCategory> categoryList = goodsCategoryMapper.selectByExample(example);
        return categoryList.stream()
                .filter(goodsCategory -> goodsCategory.getParentId() == (short) 0)
                .map(goodsCategory -> {
                    goodsCategory.setChildList(selectChildCategory(goodsCategory, categoryList));
                    return goodsCategory;
                })
                .sorted(Comparator.comparingInt(GoodsCategory::getSortOrder))
                .collect(Collectors.toList());
    }

    /**
     * 修改商品分类
     * @param goodsCategory 商品分类信息
     * @return 结果集
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public BaseResult exitGoodsCategory(GoodsCategory goodsCategory) {
        AssertUtil.isTrue(goodsCategory == null,"提交信息为空!");
        int i = goodsCategoryMapper.updateByPrimaryKeySelective(goodsCategory);
        return i > 0 ? BaseResult.success() : BaseResult.error();
    }

    /**
     * 根据id查询商品分类
     * @param id id
     * @return 商品分类
     */
    @Override
    public GoodsCategory selectCategoryById(Short id) {
        AssertUtil.isTrue(id == null || id <= 0,"商品ID不合法!");
        GoodsCategory goodsCategory = goodsCategoryMapper.selectByPrimaryKey(id);
        AssertUtil.isTrue(goodsCategory == null, "该数据不存在!");
        return goodsCategory;
    }

    /**
     * 根据id删除商品分类
     * @param id id
     * @return 结果集
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public BaseResult delCategoryById(Short id) {
        AssertUtil.isTrue(id == null || id <= 0,"商品ID不合法!");
        BaseResult baseResult = new BaseResult();
        GoodsCategory goodsCategory = goodsCategoryMapper.selectByPrimaryKey(id);
        List<GoodsCategory> categoryList = goodsCategoryMapper.selectByExample(new GoodsCategoryExample());
        List<GoodsCategory> res = selectChildCategory(goodsCategory, categoryList);
        if (res==null || res.size() == 0) {
            if (goodsCategoryMapper.deleteByPrimaryKey(id) > 0) {
                baseResult.setMsg("删除["+goodsCategory.getName()+"]分类成功!");
                baseResult.setCode(200);
                return baseResult;
            }
        }
        baseResult.setCode(500);
        baseResult.setMsg("该分类还存在子分类，无法直接删除!");
        return baseResult;
    }


    /**
     * 查询全部分类
     * @return 列表
     */
    @Override
    public List<GoodsCategory> selectAllCategory() {
        List<GoodsCategory> res = null;
        String redisKey = "goods_category::list";
        // 1、判断redis中是否存在key
        if (redisTemplate.hasKey(redisKey)) {
            // 2、若存在，将redis中的数据返回
            res = (List<GoodsCategory>) redisTemplate.opsForValue().get(redisKey);
            if (!CollectionUtils.isEmpty(res))
                return res;
        }
        // 3、若不存在，在数据库中查询数据
        res = goodsCategoryMapper.selectByExample(new GoodsCategoryExample());
        // 4、将数据存入redis中
        if (!CollectionUtils.isEmpty(res)) {
            redisTemplate.opsForValue().set(redisKey,res);
        }
        return res;
    }


    /**
     * 获取目标商品分类的子分类
     * @param temp 目标商品分类
     * @param all 全部分类
     * @return 子分类
     */
    private List<GoodsCategory> selectChildCategory(GoodsCategory temp, List<GoodsCategory> all) {
        return all.stream()
                .filter(goodsCategory -> goodsCategory.getParentId().equals(temp.getId()))
                .map(goodsCategory -> {
                    goodsCategory.setChildList(selectChildCategory(goodsCategory,all));
                    return goodsCategory;
                })
                .sorted(Comparator.comparingInt(GoodsCategory::getSortOrder))
                .collect(Collectors.toList());
    }


}
